package PrjWsMQ

import (
	"dgo/goutils/utils"
	"fmt"
	"golang.org/x/net/websocket"
	"time"
)

type WsConnWrapper struct {
	conn           *websocket.Conn
	closeEventList *utils.SyncQueue
	TagPtr         interface{}
}

type WsConnEvent func(wsconn *WsConnWrapper)

func NewWsConnWrapper(conn *websocket.Conn) *WsConnWrapper {
	rval := &WsConnWrapper{conn: conn,
		closeEventList: utils.NewSyncQueue(),
	}
	return rval
}

func (this *WsConnWrapper) RemoteAddr() string {
	return this.conn.RemoteAddr().String()
}

func (this *WsConnWrapper) onClose(code int, text string) error {
	this.closeEventList.Range(func(idx int, value interface{}, removeit *bool) bool {
		if value != nil {
			if cb, ok := value.(WsConnEvent); ok {
				cb(this)
			}
		}
		return true
	})
	return nil
}

func (this *WsConnWrapper) onRecv(msgtype int, buf []byte) error {

	return nil
}

func (this *WsConnWrapper) SendMsg(data interface{}) error {
	if str, ok := data.(string); ok {
		this.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
		return SendWsMessageEx(this.conn, WS_MESSAGE_TEXT, []byte(str))
	}

	if buf, ok := data.([]byte); ok {
		this.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
		return SendWsMessageEx(this.conn, WS_MESSAGE_BINARY, buf)
	}

	str := fmt.Sprintf("%v", data)
	this.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
	return SendWsMessageEx(this.conn, WS_MESSAGE_TEXT, []byte(str))
}

func (this *WsConnWrapper) AddCloseListener(event WsConnEvent) {
	this.closeEventList.Push(event)
}

func (this *WsConnWrapper) ResponseAsJSON(kvPairs ...interface{}) {
	if len(kvPairs) == 0 {
		if str, ok := kvPairs[0].(string); ok {
			this.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
			SendWsMessageEx(this.conn, WS_MESSAGE_TEXT, []byte(str))
		} else if buf, ok := kvPairs[0].([]byte); ok {
			this.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
			SendWsMessageEx(this.conn, WS_MESSAGE_BINARY, buf)
		}
		return
	}
	var jb utils.JSONBuilder
	jb.AddObjectEx(jb.EscapeSimpleVal, kvPairs...)
	this.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
	SendWsMessageEx(this.conn, WS_MESSAGE_TEXT, jb.Bytes())
}
